using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace DuplexTransformers
{
    public class TypeInspector
    {
        public static IList<DiscoveredProperty> GetProperties(Type type)
        {
            var result = new List<DiscoveredProperty>();
            Visit(type, result, "", null);
            return result;
        }

        private static void Visit(Type type, ICollection<DiscoveredProperty> register, string prefix, MemberExpression parentExpr)
        {
            foreach (var propertyInfo in type.GetProperties())
            {
                //if (propertyInfo.GetGetMethod() == null || propertyInfo.GetSetMethod(true) == null) continue;

                var parameterExpression = Expression.Parameter(type, "x");
                MemberExpression memberExpression = null;
                LambdaExpression lambdaExpression;

                if (parentExpr == null)
                {
                    memberExpression = Expression.Property(parameterExpression, propertyInfo);
                    lambdaExpression = Expression.Lambda(memberExpression, parameterExpression);
                }
                else
                {
                    memberExpression = Expression.Property(parentExpr, propertyInfo);
                    lambdaExpression = Expression.Lambda(memberExpression, (ParameterExpression)parentExpr.Expression);
                }

                var name = prefix + propertyInfo.Name;

                var discoveredProperty = new DiscoveredProperty(type, propertyInfo, prefix, lambdaExpression);
                register.Add(discoveredProperty);

                if (propertyInfo.PropertyType.Namespace.StartsWith("System")) continue;
                Visit(propertyInfo.PropertyType, register, name, memberExpression);
            }
        }
    }
}